import Component from "../Component.js";
import Type from "../../experience/db/Type.js";

const Draw = ol.interaction.Draw;
const VectorSource = ol.source.Vector;
const LineString = ol.geom.LineString;
const Point = ol.geom.Point;
const Feature = ol.Feature;
const Stroke = ol.style.Stroke;
const Style = ol.style.Style;
const Icon = ol.style.Icon;

export default class Fault extends Component {
    constructor() {
        super();

        this.draw = null;
        this.faultStart = [0, 0];
        this.faultEnd = [0, 0];
        this.emitter.on("faultage-sensor-move", () => {
            const config = this.algo.getConfig();
            if (config === null) {
                this.toast('请优先选择煤矿。');
                return;
            }

            this.toast('请添加一条线段,双击结束操作。')
            this.create();
        });
    }

    gfn(coordinates, geometry) {
        const center = coordinates[0];
        const last = coordinates[coordinates.length - 1];
        const newCoordinates = [];
        newCoordinates.push([center[0], center[1]]);
        newCoordinates.push([last[0], last[1]])
        newCoordinates.push(newCoordinates[0].slice());
        if (!geometry) {
            geometry = new LineString(newCoordinates);
        } else {
            geometry.setCoordinates(newCoordinates);
        }
        return geometry
    }

    create() {
        const source = new VectorSource();
        const draw = new Draw({ source: source, type: 'LineString', geometryFunction: this.gfn });
        draw.on('drawend', (event) => {
            const line = new Feature()
            const stoke = new Stroke({ width: 1, color: 'red' })
            line.setStyle(new Style({ stroke: stoke }))
            const coordinates = event.feature.getGeometry().getCoordinates()
            const start = coordinates[0], end = coordinates[1]

            // 保存开始点和结束点
            this.faultStart = [0, 0];
            this.faultEnd = [0, 0];
            this.faultStart[0] = this.algo.denormalX(start[0]);
            this.faultStart[1]  = this.algo.denormalY(start[1]);
            this.faultEnd[0] = this.algo.denormalX(end[0]);
            this.faultEnd[1] = this.algo.denormalY(end[1]);

            this.utils.setLocalStorage("faultStart", this.faultStart);
            this.utils.setLocalStorage("faultEnd", this.faultEnd);

            line.setGeometry(new LineString([start, end]));
            this.drawer.source(Type.Modify).addFeature(line);
            this.toast('请在地图上选择①或者②来确定断层方向。')

            // 计算两点之间的中心点,以及中心点到其中一个点的距离
            const x = (start[0] + end[0]) / 2, y = (start[1] + end[1]) / 2;
            const r = this.algo.distance(start[0], start[1], x, y) / 2;
            const k = this.algo.k(x, y, start[0], start[1]);

            // 描画点①
            const point1 = new Feature();
            point1.setId("fault-1");
            const x1 = x + r * Math.cos(Math.PI / 2 + k);
            const y1 = y + r * Math.sin(Math.PI / 2 + k);
            const icon1 = new Icon({ src: "../../assets/images/1_round_solid.png"});
            point1.setStyle(new Style({ image: icon1 }));
            point1.setGeometry(new Point([x1, y1]));
            this.drawer.source(Type.Modify).addFeature(point1);

            // 描画点②
            const point2 = new Feature();
            point2.setId("fault-2");
            const x2 = x + r * Math.cos(-Math.PI / 2 + k);
            const y2 = y + r * Math.sin(-Math.PI / 2 + k);
            const icon2 = new Icon({ src: "../../assets/images/2_round_solid.png"});
            point2.setStyle(new Style({ image: icon2 }));
            point2.setGeometry(new Point([x2, y2]));
            this.drawer.source(Type.Modify).addFeature(point2);

            this.drawer.removeInteraction(draw);
        })
        this.drawer.addInteraction(draw);
    }

    clear() {
        this.$$('#fault-name').val('');
        this.$$('#fault-dip').val('');
        this.$$('#fault-throw').val('');
        this.drawer.source(Type.Modify).clear();
    }

    async refresh() {
        const config = this.algo.getConfig();
        if (config == null) return;
        const data = await this.api.getFaultList(config.mine_code);
        await this.db.refresh(Type.Fault, data.data);
        await this.drawer.draw(Type.Fault);
    }

    template() {
        const div = `
            <div class="popup fault-popup" style="width: 420px; height: 260px;">
                <header>添加断层信息</header>
                <article>
                    <div class="page-content hide-navbar-on-scroll">
                        <div class="list inline-labels no-hairlines-md">
                            <ul>
                                <li class="item-content item-input">
                                    <div class="item-inner">
                                        <div class="item-label">断层名称</div>
                                        <div class="item-input-wrap">
                                            <label for="fault-name">
                                                <input type="text" value="" id="fault-name">
                                            </label>
                                        </div>
                                    </div>
                                </li>
                                <li class="item-content item-input">
                                    <div class="item-inner">
                                        <div class="item-label">倾斜角度</div>
                                        <div class="item-input-wrap">
                                            <label for="fault-dip">
                                                <input type="text" value="" id="fault-dip">
                                            </label>
                                        </div>
                                    </div>
                                </li>
                                <li class="item-content item-input">
                                    <div class="item-inner">
                                        <div class="item-label">落差</div>
                                        <div class="item-input-wrap">
                                            <label for="fault-throw">
                                                <input type="text" value="" id="fault-throw">
                                            </label>
                                        </div>
                                    </div>
                                </li>
                            </ul>
                        </div>
                    </div>
                </article>
                <footer>
                    <button class="button button-fill color-primary" id="fault-submit">确定</button>
                    <button class="button button-fill color-gray" id="fault-cancel">取消</button>
                </footer>
            </div>
        `;
        this.$$('#app').append(div);
    }

    control() {
        // 从选择器接收发来的消息
        this.emitter.on("fault-deleted", async () => {
            this.emitter.locked = true;

            const id = this.emitter.params[0], self = this;
            const dialog = self.app.dialog.confirm('确认将服务器的数据删除?', async () => {
                const config = self.algo.getConfig();
                const data = await self.api.deleteFault({ faultCode: id });
                self.toast(data.msg);

                const data2 = await this.api.getFaultList(config.mine_code);
                if (data2.data === null) {
                    console.log("断层数据获取异常。", data2);
                    return;
                }
                await self.db.refresh(Type.Fault, data2.data);
                await self.drawer.draw(Type.Fault);

                this.emitter.emit("cancel-selected");
                this.emitter.locked = false;

                const json = { id: data.data, from: "tank", type: "refreshFault" };
                window.parent.postMessage(JSON.stringify(json), '*');
            }, () => {
                this.emitter.emit("cancel-selected");
                this.emitter.locked = false;
                dialog.close();
            });
        });

        this.emitter.on("fault-select-no", async () => {
            this.emitter.locked = true;

            const feature = this.emitter.params[0], self = this;
            self.$$(".popup").css('left', self.utils.left(460));
            self.popup = self.app.popup.create({ el: '.fault-popup' });
            self.popup.open();

            self.$$("#fault-submit").on("click", async () => {
                const coordinates = feature.getGeometry().getCoordinates()
                const drop = [0, 0];
                const config = self.algo.getConfig()
                drop[0] = self.algo.denormalX(coordinates[0]);
                drop[1] = self.algo.denormalY(coordinates[1]);

                const start = self.utils.getLocalStorage("faultStart");
                const end = self.utils.getLocalStorage("faultEnd");

                // 将断层上传服务器
                const param = {
                    directionPoint: `${drop[0]},${drop[1]}`,
                    startPoint: `${start[0]},${start[1]}`,
                    endPoint: `${end[0]},${end[1]}`,
                    faultCode: self.$$('#fault-name').val(),
                    faultDip: self.$$('#fault-dip').val(),
                    faultName: self.$$('#fault-name').val(),
                    faultThrow: self.$$('#fault-throw').val(),
                    mineCode: config.mine_code,
                    mineName: config.mine_name
                }
                const data = await self.api.insertFault(param);
                self.toast(data.msg)

                // 如果toast上传成功,重新描画断层
                if (data.code === 0) {
                    const config = self.algo.getConfig();
                    if (config == null) return;

                    const data2 = await this.api.getFaultList(config.mine_code);
                    if (data2.data === null) {
                        console.log("富水区域数据获取异常。", data2);
                        return;
                    }
                    await self.db.refresh(Type.Fault, data2.data);
                    await self.drawer.draw(Type.Fault);

                    const json = { id: data.data, from: "tank", type: "refreshFault" };
                    window.parent.postMessage(JSON.stringify(json), '*');
                }

                this.emitter.emit("cancel-selected");
                this.emitter.locked = false;

                // 初始化控件
                self.clear();
                self.popup.close();
            })

            self.$$("#fault-cancel").on("click", () => {
                this.emitter.emit("cancel-selected");
                this.emitter.locked = false;
                self.clear();
                self.popup.close();
            })
        });

        this.$$("#fault").on("click", () => {
            const config = this.algo.getConfig();
            if (config === null) {
                this.toast('请优先选择煤矿。');
                return;
            }
            this.toast('请添加一条线段,双击结束操作。')
            this.create();
        })
    }
}